package org.xml.xpath4js.client;

/* 
xpath4js is a GWT implementation of XPath 2.0 
Copyright (C) 2010  Peter Schonefeld (peter dot schonefeld at gmail)

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

import com.google.gwt.xml.client.Document;
import com.google.gwt.xml.client.NamedNodeMap;
import com.google.gwt.xml.client.Node;
import com.google.gwt.xml.client.NodeList;
import com.google.gwt.xml.client.XMLParser;

//for parsing XML input and also mapping nodes from 
//the original input to items in the result sequence
public class XPathInput {
	
	public Document XmlDoc = XMLParser.createDocument();
	public XPathNode XPathDoc = new XPathNode("","xs:anyType",1,null,"",XPathNodeType.DOCUMENT_NODE,"",null);
	
	public XPathInput(Document document){
		XmlDoc = document;
		XPathDoc._qName = XmlDoc.getDocumentElement().getNodeName();
		XPathDoc.DomObject = XmlDoc.getDocumentElement();
		XPathDoc.stringValue = XmlDoc.getNodeValue();
		traverseXml(XmlDoc.getDocumentElement(), XPathDoc);
	}
	
	public XPathInput(String xml){
		XmlDoc = XMLParser.parse(xml);
		XPathDoc._qName = XmlDoc.getDocumentElement().getNodeName();
		XPathDoc.DomObject = XmlDoc.getDocumentElement();
		XPathDoc.stringValue = XmlDoc.getNodeValue();
		traverseXml(XmlDoc.getDocumentElement(), XPathDoc);
	}
	
	private void traverseXml(Node node, XPathNode xpnode){
		if(node.hasChildNodes()){
			NodeList childlist = node.getChildNodes(); 
			if(childlist!=null){
				for(int i=0;i<childlist.getLength();i++){
					Node child = childlist.item(i);
					XPathNodeType xptype = XPathNodeType.ELEMENT_NODE; //GWT Compile
					switch(child.getNodeType()){
						case 1: xptype = XPathNodeType.ELEMENT_NODE; break;
						case 2: xptype = XPathNodeType.ATTRIBUTE_NODE; break;
						case 3: xptype = XPathNodeType.TEXT_NODE; break;
						case 4: xptype = XPathNodeType.CDATA_SECTION_NODE; break;
						case 5: xptype = XPathNodeType.ENTITY_REFERENCE_NODE; break;
						case 6: xptype = XPathNodeType.ENTITY_NODE; break;
						case 7: xptype = XPathNodeType.PROCESSING_INSTRUCTION_NODE; break;
						case 8: xptype = XPathNodeType.COMMENT_NODE; break;
						case 9: xptype = XPathNodeType.PROCESSING_INSTRUCTION_NODE; break;
						case 10: xptype = XPathNodeType.DOCUMENT_TYPE_NODE; break;
						case 11: xptype = XPathNodeType.DOCUMENT_FRAGMENT_NODE; break;
						case 12: xptype = XPathNodeType.NOTATION_NODE; break;				
					}
					XPathNode xpchild = new XPathNode(child.getNodeValue(),"xs:anyType", i+1, this.XPathDoc, "", xptype, child.getNodeName(), xpnode); 		                
					xpchild.DomObject = child;
					if(xptype != XPathNodeType.ATTRIBUTE_NODE){
						xpnode.AppendChild(xpchild);
						traverseXml(child, xpchild);
						if(child.getNodeType() ==  1){ //is element node and might have attrs
							NamedNodeMap attrs = child.getAttributes();
							for(int j = 0; j < attrs.getLength(); j++){
								XPathNode xpattr = new XPathNode(attrs.item(j).getNodeValue(),"xs:anyType", j+1, this.XPathDoc, "", XPathNodeType.ATTRIBUTE_NODE, attrs.item(j).getNodeName(), xpnode);						
								xpattr.DomObject = attrs.item(j);
								xpnode.AppendAttribute(xpattr);
							}
						}
					}
				}
			}
		}
		if(node.getNodeType() ==  1){ //is element node and might have attrs
			NamedNodeMap attrs = node.getAttributes();
			for(int i = 0; i < attrs.getLength(); i++){
				XPathNode xpattr = new XPathNode(attrs.item(i).getNodeValue(),"xs:anyType", i+1, this.XPathDoc, "", XPathNodeType.ATTRIBUTE_NODE, attrs.item(i).getNodeName(), xpnode);						
				xpattr.DomObject = attrs.item(i);
				xpnode.AppendAttribute(xpattr);
			}
		}
	}  		
}